home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / PATHNAME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-03  |  3.8 KB  |  159 lines

  1. /* Convert relative to absolute pathnames
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "commands.h"
  6. #include "dirutil.h"
  7. #ifdef CALLSERVER
  8. extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:"  */
  9. #endif
  10.  
  11. #if !defined(_lint)
  12. static char rcsid[] OPTIONAL = "$Id: pathname.c,v 1.12 1996/09/04 01:34:13 root Exp root $";
  13. #endif
  14.  
  15. void crunch (char *buf,const char *path);
  16.  
  17. /* Given a working directory and an arbitrary pathname, resolve them into
  18.  * an absolute pathname. Memory is allocated for the result, which
  19.  * the caller must free
  20.  */
  21. char *
  22. pathname (cd, path)
  23. const char *cd;    /* Current working directory */
  24. const char *path;    /* Pathname argument */
  25. {
  26. register char *buf;
  27. #ifdef    MSDOS
  28. char *cp,c;
  29. char *tbuf = NULLCHAR;
  30. int tflag = 0;
  31. #endif
  32. #ifdef CALLSERVER
  33. int drive = 0;  /* is there a drive spec to preserve? */
  34. #endif
  35.  
  36.     if(cd == NULLCHAR || path == NULLCHAR)
  37.         return NULLCHAR;
  38.  
  39. #ifdef    MSDOS
  40.     /* If path has any backslashes, make a local copy with them
  41.      * translated into forward slashes
  42.      */
  43.     if (strchr (path, '\\') != NULLCHAR){
  44.         tflag = 1;
  45.         cp = tbuf = strdup (path);
  46.         while ((c = *path++) != '\0'){
  47.             if(c == '\\')
  48.                 *cp++ = '/';
  49.             else
  50.                 *cp++ = c;
  51.         }
  52.         *cp = '\0';
  53.         path = tbuf;
  54.     }
  55. #endif
  56.  
  57.     /* Strip any leading white space on args */
  58.     cd = skipwhite (cd);
  59.     path = skipwhite (path);
  60.  
  61. #ifdef CALLSERVER
  62.     if (CDROM != NULLCHAR && strncmp (path, CDROM, 2) == 0)  {
  63.         buf = strdup (path);
  64.         return buf;
  65.     }
  66.     if (CDROM != NULLCHAR &&  strncmp(cd, CDROM, 2) == 0)
  67.         drive = 1;
  68.                                                             /* make a note  */
  69. #endif
  70.     /* Allocate and initialize output buffer; user must free */
  71.     buf = mallocw ((unsigned)strlen (cd) + strlen (path) + 10);    /* fudge factor */
  72.     buf[0] = '\0';
  73.  
  74.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  75.     if (path[0] != '/')    {
  76.         if (cd[0] != '/' && cd[0] != '.')
  77.             strcpy (buf, ".");
  78.         crunch (buf, cd);
  79.     }
  80.  
  81. #ifdef CALLSERVER
  82.     else
  83.         drive = 0;
  84. #endif
  85.     crunch (buf, path);
  86.  
  87.     /* Special case: null final path means the root directory */
  88.     if (buf[0] == '\0'){
  89.         buf[0] = '/';
  90.         buf[1] = '\0';
  91.     }
  92. #ifdef    MSDOS
  93.     if (tflag && tbuf)
  94.         free (tbuf);
  95. #endif
  96. #ifdef CALLSERVER
  97.     if (drive)  {
  98.         cp = buf;
  99.         while (*cp != '\0')
  100.             *cp = *(cp++ + 1);
  101.     }
  102. #endif
  103.     return buf;
  104. }
  105.  
  106.  
  107. /* Process a path name string, starting with and adding to
  108.  * the existing buffer
  109.  */
  110. void
  111. crunch (buf, path)
  112. char *buf;
  113. register const char *path;
  114. {
  115. register char *cp;
  116.     
  117.  
  118.     if (!strncmp ("./", path, 2) || !strncmp ("../", path, 3))    {
  119.         strcpy (buf, path);
  120.         return;
  121.     }
  122.     cp = buf + strlen (buf);    /* Start write at end of current buffer */
  123.     
  124.     /* Now start crunching the pathname argument */
  125.     for ( ; ; )    {
  126.         /* Strip leading /'s; one will be written later */
  127.         while (*path == '/')
  128.             path++;
  129.         if (*path == '\0')
  130.             break;        /* no more, all done */
  131.         /* Look for parent directory references, either at the end
  132.          * of the path or imbedded in it
  133.          */
  134.         if (strcmp (path, "..") == 0 || strncmp (path, "../", 3) == 0){
  135.             /* Hop up a level */
  136.             if ((cp = strrchr (buf, '/')) == NULLCHAR)
  137.                 cp = buf;    /* Don't back up beyond root */
  138.             *cp = '\0';        /* In case there's another .. */
  139.             path += 2;        /* Skip ".." */
  140.             while (*path == '/')    /* Skip one or more slashes */
  141.                 path++;
  142.         /* Look for current directory references, either at the end
  143.          * of the path or imbedded in it
  144.          */
  145.         } else if (strcmp (path, ".") == 0 || strncmp (path, "./", 2) == 0){
  146.             /* "no op" */
  147.             path++;            /* Skip "." */
  148.             while (*path == '/')    /* Skip one or more slashes */
  149.                 path++;
  150.         } else {
  151.             /* Ordinary name, copy up to next '/' or end of path */
  152.             *cp++ = '/';
  153.             while (*path != '/' && *path != '\0')
  154.                 *cp++ = *path++;
  155.         }
  156.     }
  157.     *cp++ = '\0';
  158. }
  159.